import './index.less';

interface IOptionItem {
    value: string;
    label: string;
}

interface Iparams {
    option: Array<IOptionItem>;
    id: string;
    value?: string;
    placeholder?: string;
    search?: boolean;
    width?: number;
}

export default class UiSelect {
    private options: Array<IOptionItem> = []; // 选项队列
    private rednerList: Array<IOptionItem> = []; // 当前渲染的选项队列
    private outside = false; // 是否点击在空白区域
    private keywords = ''; // 搜索的关键字
    private search = false; // 是否开启搜索
    private searchVisible = false;
    private visible = false;
    private checked = ''; // 选中值
    private index = 0; // 元素下标
    private checkOption: IOptionItem | undefined;
    // 函数防抖处理-输入
    private lastTime: any; // eslint-disable-line
    private timer: NodeJS.Timeout | undefined = undefined; // eslint-disable-line
    // 初始化组件
    public Init(params: Iparams) {
        // 默认选中赋值
        if (params.value !== undefined) {
            this.checked = params.value;
        }
        // 筛选状态
        if (params.search !== undefined) {
            this.search = params.search;
        }
        this.options = params.option;
        this.rednerList = this.options;
        const old_ui = document.getElementsByClassName("ui-select");
        if (old_ui && old_ui.length) {
            this.index = old_ui.length;
        }
        const f_dom = document.getElementById(params.id);
        // ui-select
        const ui_select = document.createElement("div");
        ui_select.className = "ui-select ui-select-mod";
        ui_select.style.width = `${params.width || 150}px`;
        ui_select.setAttribute("data-index", `${this.index}`);
        ui_select.addEventListener("mousedown", () => { this.outside = true; });
        // ui-select ui-select-reveal
        const ui_select_reveal = document.createElement("div");
        ui_select_reveal.className = "ui-select-reveal";
        ui_select_reveal.addEventListener("mouseenter", this.switchClear.bind(this, true));
        ui_select_reveal.addEventListener("mouseleave", this.switchClear.bind(this, false));
        ui_select_reveal.addEventListener("click", this.inputClick.bind(this));
        // ui-select ui-select-reveal ui-select-input
        const ui_select_input = document.createElement("input");
        ui_select_input.className = "ui-select-input";
        ui_select_input.addEventListener("input", this.inputValueFn.bind(this));
        ui_select_input.addEventListener("focus", this.getFocus.bind(this));
        ui_select_input.placeholder = "";
        ui_select_input.type = "text";
        ui_select_input.value = "";
        ui_select_input.readOnly = !this.search;
        // ui-select ui-select-reveal icon-xiabian
        const icon_xiabian = document.createElement("span");
        icon_xiabian.className = "iconfont icon-xiabian";
        icon_xiabian.addEventListener("click", this.clearOrClose.bind(this), true);
        // ui-select ui-select-panel
        const ui_select_panel = document.createElement("div");
        ui_select_panel.className = "ui-select-panel";
        // ui-select ui-select-panel ui-select-option
        if (params.option.length === 0) {
            ui_select_panel.innerHTML = '<div class="ui-select-none">暂无数据~</div>';
        } else {
            for (let i = 0; i < params.option.length; i++) {
                const item = params.option[i];
                const item_dom = document.createElement('div');
                item_dom.setAttribute('data-index', `${i}`);
                item_dom.setAttribute('data-value', `${item.value}`);
                item_dom.setAttribute('data-label', `${item.label}`);
                item_dom.className = `ui-select-option ${this.checked === item.value ? 'ui-select-checked' : ''}`;
                item_dom.addEventListener('click', this.optionClick.bind(this, item));
                item_dom.innerText = item.label;
                if (this.checked === item.value) {
                    this.checkOption = item;
                    ui_select_input.value = item.label;
                }
                ui_select_panel.appendChild(item_dom);
            }
        }
        // 在目标处生成组件.chec.checkOption
        ui_select_reveal.appendChild(ui_select_input);
        ui_select_reveal.appendChild(icon_xiabian);
        ui_select.appendChild(ui_select_reveal);
        ui_select.appendChild(ui_select_panel);
        f_dom?.appendChild(ui_select);
        window.addEventListener('mouseup', this.onSpaceFn.bind(this));
    }
    // 清除/关闭下拉函数
    private clearOrClose(e) {
        e.stopPropagation();
        e.preventDefault();
        if (!e.target.classList.contains('icon-xiabian')) {
            this.clearFn()
        }
    }
    // 设置下拉面板状态
    private setVisible(value: boolean): void {
        this.visible = value;
        if (value) {
            this.getRevealDom().classList.add("ui-select-focus");
            this.getPanelDom().classList.add("ui-select-show");
        } else {
            this.getRevealDom().classList.remove("ui-select-focus");
            this.getPanelDom().classList.remove("ui-select-show");
            if (this.keywords !== '') {
                this.keywords = '';
                this.getInputDom().value = "";
                this.rednerList = this.options;
            }
        }
    }
    // 清理输入框
    private clearFn() {
        if (this.keywords === '') {
            this.checked = "";
            this.checkChange(this.checked);
            this.getInputDom().value = "";
            this.checkOption = undefined;
            const option_dom = this.getOptionDom();
            for (let i = 0; i < option_dom.length; i++) {
                option_dom[i].classList.remove('ui-select-checked');
            }
        } else {
            // 清理搜索条件并还原列表
            this.keywords = '';
            if (this.checkOption) {
                this.getInputDom().value = this.checkOption.label;
            }
            // setList(options);
        }
    }
    // 清除/下拉切换
    private switchClear(value: boolean) {
        // 显示清除按钮
        if (value) {
            if (this.getInputDom().value !== '') {
                this.getIconDom().classList.add("icon-close-circle");
                this.getIconDom().classList.remove("icon-xiabian");
            }
        } else {
            this.getIconDom().classList.add("icon-xiabian");
            this.getIconDom().classList.remove("icon-close-circle");
        }
    }
    // 点击输入框
    private inputClick() {
        if (!this.visible) {
            this.setVisible(true);
        }
    }
    // 输入搜索关键字
    private inputValueFn(e) {
        this.keywords = e.target.value;
        this.debounce(() => {
            this.searchFn(this.keywords);
        }, 500);
    }
    // 本地模糊搜索
    private searchFn(value: string) {
        if (value === '') {
            this.rednerList = this.options;
        } else {
            this.rednerList = this.options.filter(item => {
                return item.label.includes(value);
            });
        }
        this.renderOptions();
    }
    // render 渲染选项队列
    private renderOptions() {
        this.getPanelDom().innerHTML = '';
        let isChecked = false;
        for (let i = 0; i < this.rednerList.length; i++) {
            const item = this.rednerList[i];
            isChecked = this.checked === item.value;
            const item_dom = document.createElement('div');
            item_dom.setAttribute('data-index', `${i}`);
            item_dom.setAttribute('data-value', `${item.value}`);
            item_dom.setAttribute('data-label', `${item.label}`);
            item_dom.className = `ui-select-option ${this.checked === item.value ? 'ui-select-checked' : ''}`;
            item_dom.addEventListener('click', this.optionClick.bind(this, item));
            item_dom.innerText = item.label;
            this.getPanelDom().appendChild(item_dom);
            if (this.checked === item.value) {
                this.getInputDom().value = item.label;
            }
        }
        if (!isChecked && this.keywords === '') this.getInputDom().value = '';
        if (this.rednerList.length === 0) {
            this.getPanelDom().innerHTML = '<div class="ui-select-none">暂无数据~</div>';
        }
    }
    // 
    private getFocus() {
        // if (this.searchVisible) {
        //     this.setInputValue(keywords);
        // }
    }
    // 防抖
    private debounce(fn: () => void, wait: number) {
        const now: any = new Date(); //eslint-disable-line
        if (this.lastTime - now < wait) {
            clearTimeout(this.timer);
        }
        this.timer = setTimeout(() => {
            fn();
            this.lastTime = +new Date();
        }, wait);
    }
    // click 选中事件
    private optionClick(item: IOptionItem) {
        this.checked = item.value;
        this.checkChange(this.checked);
        const option_dom = this.getOptionDom();
        for (let i = 0; i < option_dom.length; i++) {
            const item_value = option_dom[i].getAttribute('data-value');
            if (item_value == item.value) {
                option_dom[i].classList.add('ui-select-checked');
            } else {
                option_dom[i].classList.remove('ui-select-checked');
            }

        }
        this.getInputDom().value = item.label;
        this.checkOption = item;
        this.keywords = '';
        this.setVisible(false);
    }
    // 点击空白判断
    private onSpaceFn() {
        if (this.outside) {
            this.outside = false;
        } else {
            this.setVisible(false);
        }
    }
    // 重新设置选项队列
    public setOptions(list: Array<IOptionItem>, checked?: string) {
        if (checked !== undefined && checked !== '') {
            this.checked = checked;
        }
        this.options = list;
        this.rednerList = list;
        this.renderOptions()
    }
    // 值改变
    public changeFn(fn) {
        this.checkChange = fn;
    }
    // 
    checkChange(value: string) {
    }
    // get ui-select
    private getSelectDom() {
        const select_dom_list = document.getElementsByClassName('ui-select');
        let select_dom: HTMLDivElement | null = null;
        for (let i = 0; i < select_dom_list.length; i++) {
            if (Number(select_dom_list[i].getAttribute('data-index')) == this.index) {
                select_dom = select_dom_list[i] as HTMLDivElement;
            }
        }
        return select_dom as HTMLDivElement;
    }
    // get ui-select-reveal
    private getRevealDom() {
        return this.getSelectDom().children[0] as HTMLDivElement;
    }
    // get ui-select-panel
    private getPanelDom() {
        return this.getSelectDom().children[1] as HTMLDivElement;
    }
    // get ui-select-input
    private getInputDom() {
        return this.getRevealDom()?.firstChild as HTMLInputElement;
    }
    // get ui-select-option
    private getOptionDom() {
        return this.getPanelDom()?.children as HTMLCollection;
    }
    // get ui-select-xiabian
    private getIconDom() {
        return this.getRevealDom()?.lastChild as HTMLElement;
    }
}
